SPDX-FileCopyrightText: 2013 Nourdin Ben Abbou SPDX-FileCopyrightText: 2024 AlICe laboratory https://alicelab.be
SPDX-License-Identifier: GPL-3.0-or-later
script façades Alberti 20/01/2013 développé sous Blender 2.68a / windows Ben Abbou Nourdin MA2
import bpy
import random
bpy.ops.object.select_all(action="SELECT")
bpy.ops.object.delete(use_global=False)
bpy.context.scene.layers[0] = True
bpy.ops.object.camera_add(
    view_align=True,
    enter_editmode=False,
    location=(-87.33089, 170.25224, 108.77956),
    rotation=(1.1432193, 0, 3.589),
    layers=(
        True,
        False,
        False,
        False,
        False,
        False,
        False,
        False,
        False,
        False,
        False,
        False,
        False,
        False,
        False,
        False,
        False,
        False,
        False,
        False,
    ),
)
bpy.context.object.data.type = "ORTHO"
bpy.context.object.data.ortho_scale = 80
bpy.context.object.data.clip_end = 300.5
bpy.context.scene.render.resolution_x = 2000
bpy.context.scene.render.resolution_y = 2000
bpy.context.scene.render.resolution_percentage = 100bpy.context.scene.render.layers[“calque_1”].name = “calque_1”’‘’ bpy.ops.scene.freestyle_lineset_add()
--------------------------------------------------------------------------------# # VARIABLES GENEREES # # --------------------------------------------------------------------------------#
composition_plan = ["novella", "maletestino", "sebastiano", "andréa"]
entraxe_possible = [
    (1 / 2, 1 / 6, -1 / 6, -1 / 2),
    (1 / 2, 1 / 10, -1 / 10, -1 / 2),
    (1 / 2, 1 / 4, -1 / 4, -1 / 2),
]
entraxe = random.choice(entraxe_possible)
largeur_façade = 20
epaisseur_façade = 0.2
profondeur_vestibule = largeur_façade / 4
nbr_etage_possible = [1, 2, 3]
nbr_etage = random.choice(nbr_etage_possible)
hauteur_tambour = 0.5
diametre = 0.7
nbr_tambour_possible = [10, 11, 12]  # par étage !
nbr_tambour = random.choice(nbr_tambour_possible)
nbr_tambour_total = nbr_tambour * nbr_etage
chapiteau_possible = [
    "dorique",
]
chapiteau = random.choice(chapiteau_possible)
hauteur_chapiteau = 0.3
hauteur = nbr_tambour * hauteur_tambour
hauteur_cella = nbr_etage * hauteur
sol_possible = ["sol plat", "socle", "sol creux"]
sol = random.choice(sol_possible)
fronton_possible = [
    "simple triangle",
    "simple circulaire",
    "volute triangle",
    "volute circulaire",
]
fronton = random.choice(fronton_possible)
colonnes_possible = ["cercle", "rectangle"]
colonne = random.choice(colonnes_possible)
façade_possible = ["plaquée", "à vestibule"]
façade = random.choice(façade_possible)--------------------------------------------------------------------------------# # FONCTIONS DE BASE # # fonctions d’aide à l’écriture rapide # --------------------------------------------------------------------------------#
racourcis pour générer des géométries
cube = bpy.ops.mesh.primitive_cube_add
cylindre = bpy.ops.mesh.primitive_cylinder_add
resize = bpy.ops.transform.resize
selection = bpy.context.scene.objects
rotation = bpy.ops.transform.rotates’éxecute comme rotation (value = 1.5708, axis = (0,0,1)) où 90° = 1.5708 où les axes sont (x,y,z) tel quel seulement x == (1,0,0)
fonction volume, déterminer son nom, sa location, sa taille
def Volume(nom, location, size):
    cube(location=location)
    resize(value=(0.5, 0.5, 0.5))
    resize(value=size)
    bpy.context.object.name = nomdef Volume01(nom, location, size):
    cylindre(location=location)
    resize(value=(0.5, 0.5, 0.5))
    resize(value=size)
    bpy.context.object.name = nomfonction booléenne: déterminer deux objets, plein et vide, par leurs noms entre “” déterminer si le vide doit être caché (hide) par True ou False
def Boolean(plein, vide, hide):
    Plein = bpy.data.objects[plein]
    Vide = bpy.data.objects[vide]
    selection.active = Plein
    bpy.ops.object.modifier_add(type="BOOLEAN")
    bpy.context.object.modifiers["Boolean"].operation = "DIFFERENCE"
    bpy.context.object.modifiers["Boolean"].object = bpy.data.objects[vide]
    bpy.ops.object.modifier_apply(apply_as="DATA", modifier="Boolean")
    selection.active = Vide
    bpy.ops.object.delete(use_global=False)bpy.context.object.hide = hide bpy.context.object.hide_render = hide
fonction solidification: déterminer l’objet par son nom entre “” et son épaisseur
def Solidify(objet, epaisseur):
    Obj = bpy.data.objects[objet]
    selection.active = objet
    bpy.ops.object.modifier_add(type="SOLIDIFY")
    bpy.context.object.modifiers["Solidify"].thickness = epaisseur------------------------------------------------------------------------------# # FONCTIONS DES PARTIES # # parties composites générateurs d’éléments principaux du temple # ------------------------------------------------------------------------------#
def Tambour(location, size, empillement):
    if empillement != nbr_tambour_total - 1:
        cylindre(radius=0.5, location=location)
        resize(value=size)
        bpy.ops.object.move_to_layer(
            layers=[False] * 10 + [True] + [False] * 9
        )  # generation de mes colonnes à partir de l'empilement des tambours
    else:
        if hauteur_tambour > hauteur_chapiteau:
            dim_z = (hauteur_tambour - hauteur_chapiteau) / 2
            size = size[0], size[1], dim_z
            location = location[0], location[1], empillement * hauteur_tambour + dim_z
            cylindre(radius=0.5, location=location)
            resize(value=size)
            bpy.ops.object.move_to_layer(layers=[False] * 10 + [True] + [False] * 9)
        else:
            passdef Chapiteau(location, size):
    if chapiteau == "dorique":
        size = (size[0], size[1], hauteur_chapiteau / 2)
        Volume("dorique", location, size)
        bpy.ops.object.move_to_layer(layers=[False] * 10 + [True] + [False] * 9)
        size = (size[0] * 1.4, size[1] * 1.4, hauteur_chapiteau / 2)
        location = (location[0], location[1], location[2] + hauteur_chapiteau / 2)
        Volume("dorique", location, size)
        bpy.ops.object.move_to_layer(layers=[False] * 10 + [True] + [False] * 9)
    else:
        pass  # à déterminer chapiteau de type ionique ...------------------------------------------------------------------------------# # FONCTIONS DU BÂTIMENTS # # Eléments principaux du temple # ------------------------------------------------------------------------------#
definition des différents types de sol:
def Sol():
    if sol == "sol plat":
        Volume("sol plat", (0, -10, -1.15), (40, 80, 2.3))
    elif sol == "socle":
        Volume("sol plat", (0, -10, -2.35), (40, 80, 2.3))
        Volume("socle", (0, -15, -0.6), (20, 50, 1.2))
    elif sol == "sol creux":
        Volume("sol plat", (0, -10, 0), (40, 80, 2.3))
        Volume("sol creux", (0, -15, 0.6), (20, 50, 1.2))
        Boolean("sol plat", "sol creux", True)Execution du terrain
Sol()Definition des colonnes
def Colonne(location):
    pos_x, pos_y = location
    size = (diametre, diametre, hauteur_tambour / 2)
    for z in range(0, nbr_tambour_total):
        Tambour((pos_x, pos_y, (z * hauteur_tambour) + (hauteur_tambour / 2)), size, z)
        if z == nbr_tambour_total - 1:
            Tambour(
                (pos_x, pos_y, (z * hauteur_tambour) + (hauteur_tambour / 2)), size, z
            )
            Chapiteau(
                (
                    pos_x,
                    pos_y,
                    (z * hauteur_tambour)
                    + (hauteur_tambour - hauteur_chapiteau)
                    + hauteur_chapiteau / 4,
                ),
                size,
            )
    bpy.context.scene.layers[0] = False
    bpy.context.scene.layers[10] = True
    tambour = bpy.data.objects["Cylinder"]
    selection.active = tambour
    bpy.ops.object.select_all(action="SELECT")
    bpy.ops.object.join()
    bpy.context.object.name = "colonnes"Definition et execution des escaliers
def Marche(pos_X, pos_Y, pos_Z, dim_X, dim_Y, dim_Z):
    bpy.ops.mesh.primitive_cube_add(location=(pos_X, pos_Y + 10, pos_Z))
    bpy.ops.transform.resize(value=(0.5, 0.5, 0.5))
    bpy.ops.transform.resize(value=(20, 0.3, 0.1))def escalier():
    if sol == "socle":
        x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
        y = 10
        for k in range(0, 11):
            for i in range(0, x[y]):
                Marche(0, (k * 0.3) + 0.2, (i * 0.1) - 1.15, 1, 1, 1)
            y = y - 1
    elif sol == "sol creux":
        x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
        y = 10
        for k in range(0, 11):
            for i in range(0, x[y]):
                Marche(0, (-k * 0.3) - 0.15, (i * 0.1) + 0.05, 1, 1, 1)
            y = y - 1
escalier()definition des façades
def Façade():
    if façade == "plaquée":
        Volume(
            "frontale",
            (0, 0, hauteur_cella / 2),
            (largeur_façade, epaisseur_façade, hauteur_cella),
        )  # Porte d'entrée principale
        Volume("porte", (0, 0, (hauteur_cella - 2) / 2), (3, 1, hauteur_cella - 2))
        Boolean("frontale", "porte", True)
        for fraction in entraxe:  # position des colonnes
            Colonne(((largeur_façade - diametre) * fraction, 0))
            print(entraxe)
    elif façade == "à vestibule":
        Volume(
            "frontale",
            (0, largeur_façade / 4, hauteur_cella / 2),
            (largeur_façade, epaisseur_façade, hauteur_cella),
        )
        Volume(
            "porte",
            (0, largeur_façade / 4, (hauteur_cella - 2) / 2),
            (3, 1, hauteur_cella - 2),
        )Volume(“porte”,(largeur_façade/3,largeur_façade/4,(hauteur_cella-2)/2),(3,0.2,hauteur_cella-2)) # création des portes secondaires et des febetres Volume(“porte”,(-largeur_façade/3,largeur_façade/4,(hauteur_cella-2)/2),(3,0.2,hauteur_cella-2)) Volume01 (“porte”,(0,0,(hauteur_cella-3)/2),(3,3,1)) # arc de la porte d’enrée principale avec un cylindre horizontal rotation = bpy.ops.transform.rotate rotation (value = 1.5708, axis = (1,0,0)) bpy.ops.object.select_all(action=’SELECT’) bpy.ops.object.join() bpy.context.object.name = “porte” !!!! ne fonctionne pas très bien !!!!
        Boolean("frontale", "porte", True)
        for fraction in entraxe:
            Colonne(((largeur_façade - diametre) * fraction, largeur_façade / 4))
            print(entraxe)
            Volume(
                "laterale",
                ((largeur_façade - diametre) * fraction, 2.5, hauteur_cella / 2),
                (0.2, 5.2, hauteur_cella),
            )
            Volume("laterale", (9.9, 2.5, hauteur_cella / 2), (0.2, 5.2, hauteur_cella))
            Volume(
                "laterale", (-9.9, 2.5, hauteur_cella / 2), (0.2, 5.2, hauteur_cella)
            )
Façade()def Fronton ()…
def Toiture ()…
execution de la cella
Volume(
    "cella",
    (0, -largeur_façade - epaisseur_façade / 2, hauteur_cella / 2),
    (largeur_façade, 2 * largeur_façade, hauteur_cella),
)
Volume(
    "cornière",
    (0, -largeur_façade - epaisseur_façade / 2, (hauteur_cella) + 0.1),
    (largeur_façade + 0.4, 2 * (largeur_façade + 0.4), 0.2),
)
Volume(
    "toiture",
    (0, -largeur_façade - epaisseur_façade - 0.1 / 2, hauteur_cella),
    (13.8, 40, 13.8),
)
rotation(value=0.785398, axis=(0, 1, 0))
bpy.context.scene.layers[0] = True
bpy.context.scene.layers[10] = Trueprint("")
print("--------------------------------------------------")
print("")
print("                   COMPOSITION ")
print("")
print("//////////////////////////////////////////////////")
print("")
print("")
print("Temple sur", sol, "avec facade", façade)
print("")
print("La facade s'eleve à", hauteur_cella, "mètres du sol sur", nbr_etage, "étage.")
print("sa surface totale est de", largeur_façade * hauteur_cella, "m²")
print("")
print("nombre de colonnesest de", len(entraxe))
if entraxe == entraxe_possible[0]:
    print("l'entraxe des colonnes est de 1/3 , 1/3 , 1/3")
elif entraxe == entraxe_possible[1]:
    print("l'entraxe des colonnes est de 2/5 , 2/5 , 2/5")
elif entraxe == entraxe_possible[2]:
    print("l'entraxe des colonnes est de 1/4 , 2/4 , 1/4")
print("nombre de tambour total=", nbr_tambour_total)